
#include "turboscreencut.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QPainter>
#include <QMouseEvent>
#include <QFileDialog>
#include <QTimer>

TurboScreenCut::TurboScreenCut(QWidget *parent)
    : QWidget(parent)
{
    setWindowFlags(Qt::FramelessWindowHint);
    // setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    //取得屏幕大小
    screen_ = new TurboScreen(QApplication::desktop()->size());
    //保存全屏图像
    full_pix_ = new QPixmap();
    menu_ = new TurboMenu(this);
    menu_->setVisible(false);
    showFullScreen();
    connect(menu_, &TurboMenu::sig_btnQuitClicked, this, &TurboScreenCut::close);
    connect(menu_, &TurboMenu::sig_btnSaveClicked, this, &TurboScreenCut::saveCutScreen);
    connect(menu_, &TurboMenu::sig_btnPaintbrushClicked, this, &TurboScreenCut::drawPaintbrush);
    connect(menu_, &TurboMenu::sig_btnRectClicked, this, &TurboScreenCut::drawRect);
    connect(menu_, &TurboMenu::sig_btnEllipseClicked, this, &TurboScreenCut::drawEllipse);
    connect(menu_, &TurboMenu::sig_btnArrowClicked, this, &TurboScreenCut::drawArrow);
    connect(menu_, &TurboMenu::sig_btnMosaicClicked, this, &TurboScreenCut::drawMosaic);

    mosaic_pix_ = full_pix_->scaled(full_pix_->width()/10,full_pix_->height()/10);
    mosaic_pix_ = mosaic_pix_.scaled(full_pix_->size());

}

TurboScreenCut::~TurboScreenCut()
{

}

TurboScreenCut &TurboScreenCut::instance()
{
    static TurboScreenCut instance;
    return instance;
}

void TurboScreenCut::showEvent(QShowEvent *event)
{
    QPoint point(-1, -1);
    screen_->setMouseStartPos(point);
    screen_->setMouseEndPos(point);

    QScreen *pScreen = QApplication::primaryScreen();
    *full_pix_ = pScreen->grabWindow(QApplication::desktop()->winId(), 0, 0, screen_->getMaxWidth(),screen_->getMaxHeight());
    //设置透明度实现模糊背景
    QPixmap pix(QApplication::desktop()->width(), QApplication::desktop()->height());
    pix.fill((QColor(160, 160, 160, 80)));
    blur_pix_ = new QPixmap(*full_pix_);
    QPainter p(blur_pix_);
    p.drawPixmap(0, 0, pix);
}

void TurboScreenCut::paintEvent(QPaintEvent *event)
{
    int x = screen_->getPosLeftUp().x();
    int y = screen_->getPosLeftUp().y();
    int w = screen_->getPosRightDown().x() - x;
    int h = screen_->getPosRightDown().y() - y;

    QPainter painter(this);
    QPen pen;
    pen.setColor(Qt::green);
    pen.setWidth(1);
    pen.setStyle(Qt::SolidLine);
    painter.setPen(pen);

    QFont font;
    font.setFamily("Microsoft YaHei");
    font.setPointSize(10);
    painter.setFont(font);

    painter.drawPixmap(0, 0, *blur_pix_);

    if (w != 0 && h != 0)
    {
        painter.drawPixmap(x, y, full_pix_->copy(x, y, w, h));
    }
    painter.drawRect(x, y, w, h);
    pen.setColor(Qt::white);
    painter.setPen(pen);
    painter.drawText(x + 2, y - 8, tr(" %1 x %2 ").arg(w).arg(h));

    for(const auto &shape : shape_list_)
    {
        shape->paint(painter);
    }
    if(shape_)
    {
        shape_->paint(painter);
    }
}

void TurboScreenCut::mousePressEvent(QMouseEvent *event)
{
    int status = screen_->getStatus();
    if (status == TurboScreen::emSELECT)
    {
        screen_->setMouseStartPos(event->pos());
    }
    if (status == TurboScreen::emDRAW)
    {
        switch(current_code_)
        {
            case TurboShape::emLine:
            {
                shape_ = new Line();
                shape_->pushLinePoint(event->pos());
            }
                break;
            case TurboShape::emRect:
            {
                shape_ =  new Rect();
                shape_->setPosLeftUp( event->pos());
                shape_->setPosRightDown( event->pos());
            }
                break;
            case TurboShape::emEllipse:
            {
                shape_ =  new Ellipse();
                shape_->setPosLeftUp( event->pos());
                shape_->setPosRightDown( event->pos());
            }
                break;
            case TurboShape::emArrow:
            {
                shape_ =  new Arrow();
                shape_->setPosLeftUp( event->pos());
                shape_->setPosRightDown( event->pos());
            }
                break;
            case TurboShape::emMosaic:
            {
                shape_ =  new Mosaic();
                shape_->setMosaic(mosaic_pix_);
                shape_->pushLinePoint(event->pos());
            }
                break;
            default:
                shape_ = nullptr;
                break;
        }
    }
    else if (status == TurboScreen::emMOV)
    {
        if (!screen_->checkIsInArea(event->pos()))
        {
            screen_->setMouseStartPos(event->pos());
            screen_->setStatus(TurboScreen::emSELECT);
        }
        else
        {
            mov_pos_ = event->pos();
            this->setCursor(Qt::SizeAllCursor);
        }
    }
    update();
}

void TurboScreenCut::mouseMoveEvent(QMouseEvent *event)
{
    if(screen_->getStatus() == TurboScreen::emDRAW)
    {
        QPoint point = event->pos();
        if(point.x() < screen_->getPosLeftUp().x())
        {
            point.setX( screen_->getPosLeftUp().x());
        }
        else if(point.x() > screen_->getPosRightDown().x())
        {
            point.setX( screen_->getPosRightDown().x());
        }
        if(point.y() < screen_->getPosLeftUp().y())
        {
            point.setY( screen_->getPosLeftUp().y());
        }
        else if(point.y() > screen_->getPosRightDown().y())
        {
            point.setY( screen_->getPosRightDown().y());
        }
        switch(current_code_)
        {
            case TurboShape::emLine:
                shape_->pushLinePoint(point);
                break;
            case TurboShape::emRect:
                shape_->setPosRightDown( point);
                break;
            case TurboShape::emEllipse:
                shape_->setPosRightDown( point);
                break;
            case TurboShape::emArrow:
                shape_->setPosRightDown( point);
                break;
            case TurboShape::emMosaic:
                shape_->pushLinePoint(point);
                break;
            default:
                shape_ = nullptr;
                break;
        }
    }
    else if (screen_->getStatus() == TurboScreen::emSELECT)
    {
        screen_->setMouseEndPos(event->pos());
    }
    else if (screen_->getStatus() == TurboScreen::emMOV)
    {
        QPoint p(event->x() - mov_pos_.x(), event->y() - mov_pos_.y());
        screen_->move(p);
        mov_pos_ = event->pos();
    }
    update();
}

void TurboScreenCut::mouseReleaseEvent(QMouseEvent *event)
{
    if(screen_->getStatus() == TurboScreen::emDRAW)
    {
        shape_list_.push_back(shape_);
    }
    else if (screen_->getStatus() == TurboScreen::emSELECT)
    {
        screen_->setStatus(TurboScreen::emMOV);
    }
    else if (screen_->getStatus() == TurboScreen::emMOV)
    {
        this->setCursor(Qt::ArrowCursor);
    }
    QTimer::singleShot(20, [this](){
        update();
    });
    menu_->setVisible(true);
    menu_->move(screen_->getPosRightDown().x() - menu_->width(),screen_->getPosRightDown().y());
}

void TurboScreenCut::keyPressEvent(QKeyEvent *event)
{
    QWidget::keyPressEvent(event);
    if(event->key() == Qt::Key_Escape)
    {
        close();
    }
}

bool TurboScreenCut::event(QEvent *event)
{
    return QWidget::event(event);
}

void TurboScreenCut::saveCutScreen()
{
    QString fileName = QFileDialog::getSaveFileName(this,"save as", "", "*.png");
    if(fileName.isEmpty())
    {
        return;
    }
    int x = screen_->getPosLeftUp().x();
    int y = screen_->getPosLeftUp().y();
    int w = screen_->getPosRightDown().x() - x;
    int h = screen_->getPosRightDown().y() - y;

    QPainter painterPix(full_pix_);
    QPen penDraw(Qt::red);
    penDraw.setWidth(3);
    painterPix.setPen(penDraw);
    for(const auto &shape : shape_list_)
    {
        shape->paint(painterPix);
    }

    full_pix_->copy(x, y, w, h).save(fileName, "png");
    close();
}

void TurboScreenCut::drawPaintbrush()
{
    screen_->setStatus(TurboScreen::emDRAW);
    setCurrentCode(TurboShape::emLine);
}

void TurboScreenCut::drawRect()
{
    screen_->setStatus(TurboScreen::emDRAW);
    setCurrentCode(TurboShape::emRect);
}

void TurboScreenCut::drawEllipse()
{
    screen_->setStatus(TurboScreen::emDRAW);
    setCurrentCode(TurboShape::emEllipse);
}

void TurboScreenCut::drawArrow()
{
    screen_->setStatus(TurboScreen::emDRAW);
    setCurrentCode(TurboShape::emArrow);
}

void TurboScreenCut::drawMosaic()
{
    screen_->setStatus(TurboScreen::emDRAW);
    setCurrentCode(TurboShape::emMosaic);
}

void TurboScreenCut::setCurrentCode(TurboShape::Code code)
{
    current_code_ = code;
}

